<?php
class Database {
	protected $link = NULL;
	public static $_instance = NULL;
	public static function getInstance() {
		if (self::$_instance === NULL) {
			self::$_instance = new self;
		}
		return self::$_instance;
	}
	public function __construct() {
		$dsn = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';';
		if (!empty(DB_NAME)) {
			$dsn .= 'dbname=' . DB_NAME . ';';
		}
		$dsn .= 'charset=utf8';
		try {
			$this->link = new PDO($dsn, DB_USER, DB_PASS);
		} catch (PDOException $e) {
			echo 'Connect to database failed';
			exit;
		}
	}
	public function query($sql, $data = NULL) {
		$st = $this->link->prepare($sql);
		if ($st === FALSE) {
			throw new Exception('Failed to prepare SQL');
		}
		if (is_array($data)) {
			foreach ($data as $k => $v) {
				if (is_numeric($k)) {
					$st->bindValue($k + 1, $v);
				} else {
					$st->bindValue($k, $v);
				}
			}
		}
		try {
			$r = $st->execute();
			if ($r === FALSE) {
				$e = $st->errorInfo();
				throw new Exception($e[2]);
			}
		} catch (PDOException $e) {
			throw new Exception($e->getMessage());
		}
		$st->setFetchMode(PDO::FETCH_ASSOC);
		return $st->fetchAll();
	}
	public function getOne($sql, $data = NULL) {
		if (!preg_match('/limit ([0-9,]+)$/i', $sql)) {
			$sql .= ' LIMIT 0,1';
		}
		$r = $this->query($sql, $data);
		return current($r);
	}
	public function getLastId() {
		return $this->link->lastInsertId();
	}
}